//
//  Camera.cpp
//  OpenGL StarShip
//
//  Created by Tariqul Islam on 5/31/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#include "headers/Camera.h"

#include "SDL/SDL.h"
#include "SDL/SDL_opengl.h"

#include <math.h>
#include <iostream>
using namespace std;

Camera::Camera(){
    locked=false;
    reset();

}

Vector3d Camera::getPosition(){
    return this->position;
}

void Camera::reset() {
    this->position = Vector3d(0.0, 0.0, 0.0);
    this->along = Vector3d(1.0, 0.0, 0.0);
    this->up = Vector3d(0.0, 1.0, 0.0);
    this->forward = Vector3d(0.0, 0.0, -1.0);
    update();
}

void Camera::lockEnabled(bool b){
    this->locked = b;
}

void Camera::update(){
    double x = DOT(along, position);
    double y = DOT(up, position);
    double z = DOT(forward, position);
    
    float viewMatrix[4][4];
    viewMatrix[0][0] = along.x;
    viewMatrix[0][1] = up.x;
    viewMatrix[0][2] = -forward.x;
    viewMatrix[0][3] = 0.0f;
    
    viewMatrix[1][0] = along.y;
    viewMatrix[1][1] = up.y;
    viewMatrix[1][2] = -forward.y;
    viewMatrix[1][3] = 0.0f;
    
    
    viewMatrix[2][0] = along.z;
    viewMatrix[2][1] = up.z;
    viewMatrix[2][2] = -forward.z;
    viewMatrix[2][3] = 0.0f;
    
    
    viewMatrix[3][0] = -x;
    viewMatrix[3][1] = -y;
    viewMatrix[3][2] = z;
    viewMatrix[3][3] = 1.0f;
    
    
    glMatrixMode(GL_MODELVIEW);
    glLoadMatrixf((GLfloat *)&viewMatrix);
    
}


void Camera::pitch(GLfloat theta) {
    forward = forward * cos(theta * PI/180)+ up * sin(theta * PI/180);
    forward.norm();
    up = CROSS(forward, along) * -1.0;
    update();
}


void Camera::yaw(GLfloat theta) {
    along = along * cos(theta * PI/180)+ forward * sin(theta * PI/180);
    along.norm();
    forward = CROSS(along, up) * -1.0;
    update();
}



void Camera::roll(GLfloat theta) {
    up = up * cos(theta * PI/180) - along * sin(theta * PI/180);
    up.norm();
    along = CROSS(forward, up);
    update();
}


void Camera::walk(GLfloat delta) {
    position = position + forward * delta;
    update();
}


void Camera::fly(GLfloat delta) {
    position = position + up * delta;
  
    update();
}


void Camera::strafe(GLfloat delta) {
    position = position + along * delta;
    update();
}

void Camera::rotateTolook(){

}





